package cn.colat.micse.common.config;

import cn.colat.micse.common.code.ResCode;
import cn.colat.micse.common.constant.CommonConstant;
import cn.colat.micse.common.pojo.vo.ResBody;
import cn.dev33.satoken.context.SaHolder;
import cn.dev33.satoken.filter.SaServletFilter;
import cn.dev33.satoken.interceptor.SaInterceptor;
import cn.dev33.satoken.same.SaSameUtil;
import com.alibaba.fastjson2.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.MDC;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.util.StringUtils;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

/**
 * 在子服务添加过滤器校验参数
 */
@Slf4j
@Configuration
public class SaTokenConfigure implements WebMvcConfigurer {
    /**
     * 如果通过网关转发，可以正常访问，直接访问子服务会提示：无效Same-Token：xxx
     */
    @Bean
    public SaServletFilter getSaServletFilter() {
        SaServletFilter saServletFilter = new SaServletFilter();
        saServletFilter.addInclude("/**");
        // 排除Swagger 接口
        saServletFilter.addExclude(
                "/swagger-ui/**",
                // "/account/login",
                "/swagger-resources/**",
                "/v3/api-docs",
                "/v3/api-docs/**"
        );
        saServletFilter.setAuth(obj -> {
                    // 获取 traceId 进行日志追踪
                    String traceId = SaHolder.getRequest().getHeader(CommonConstant.TRACE_ID);
                    if (StringUtils.hasLength(traceId)) {
                        MDC.put(CommonConstant.TRACE_ID, traceId);
                    }
                    /*
                    校验 Same-Token身份凭证 -- 以下两句代码可简化为SaSameUtil.checkCurrentRequestToken();
                    */
                    String token = SaHolder.getRequest().getHeader(SaSameUtil.SAME_TOKEN);
                    log.info("{} = {}", SaSameUtil.SAME_TOKEN, token);
                    SaSameUtil.checkToken(token);
                }
        );
        saServletFilter.setError(e -> {
                    log.error("SaServletFilter 校验 Same-Token身份凭证 错误：{} ", e.getMessage());
                    return JSONObject.toJSONString(ResBody.failErrorCode(ResCode.ILLEGAL_ACCESS));
                }
        );
        return saServletFilter;
    }


    /**
     * 添加satoken拦截器
     *
     * @param registry 注册器
     */
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        // 注册 Sa-Token，打开注解式鉴权功能
        registry.addInterceptor(new SaInterceptor()).addPathPatterns("/**");
    }
}
